package net.luculent.spring.config;

import java.io.IOException;
import java.net.URLDecoder;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.client.IdleConnectionEvictor;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;

import com.alibaba.fastjson.JSONObject;

import net.luculent.controller.IndexController;
import net.luculent.utils.CommonUtils;

@Configuration
@PropertySource(value = "classpath:httpclient.properties")
public class HttpclientSpringConfig {
	
	private static final Logger logger =  LoggerFactory.getLogger(IndexController.class);
	
	@Value("${http.maxTotal}")
	private Integer httpMaxTotal;

	@Value("${http.defaultMaxPerRoute}")
	private Integer httpDefaultMaxPerRoute;

	@Value("${http.connectTimeout}")
	private Integer httpConnectTimeout;

	@Value("${http.connectionRequestTimeout}")
	private Integer httpConnectionRequestTimeout;

	@Value("${http.socketTimeout}")
	private Integer httpSocketTimeout;

	@Value("${http.staleConnectionCheckEnabled}")
	private Boolean httpStaleConnectionCheckEnabled;

	@Autowired
	private PoolingHttpClientConnectionManager manager;
	
	
	@Bean
	public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
		PoolingHttpClientConnectionManager poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
		
		//最大连接数
		poolingHttpClientConnectionManager.setMaxTotal(httpMaxTotal);
		
		//每个主机的最大并发数
		poolingHttpClientConnectionManager.setDefaultMaxPerRoute(httpDefaultMaxPerRoute);
		return poolingHttpClientConnectionManager;
	}
	
	/**
	 * 定期关闭连接
	 * @return
	 */
	@Bean
	public IdleConnectionEvictor idleConnectionEvictor() {
		return new IdleConnectionEvictor(manager, httpConnectTimeout, null);
	}

	/**
	 * 定义 Httpclient 多例对象
	 * @return
	 */
	@Bean
	@Scope("prototype")
	public CloseableHttpClient closeableHttpClient() {
		return HttpClients.custom().setConnectionManager(this.manager).build();
	}

	/**
	 * 请求配置
	 * @return
	 */
	@Bean
	public RequestConfig requestConfig() {
		return RequestConfig.custom().setConnectTimeout(httpConnectTimeout) // 创建连接的最长时间
				.setConnectionRequestTimeout(httpConnectionRequestTimeout) // 从连接池中获取到连接的最长时间
				.setSocketTimeout(httpSocketTimeout) // 数据传输的最长时间
				.setStaleConnectionCheckEnabled(httpStaleConnectionCheckEnabled) // 提交请求前测试连接是否可用
				.build();
	}
	
	/**
     * post请求
     * @param url         url地址
     * @param jsonParam     参数
     * @param noNeedResponse    不需要返回结果
     * @return
     */
    public JSONObject httpPost(String url,JSONObject jsonParam, boolean noNeedResponse){
        //post请求返回结果
        HttpClient httpClient = this.closeableHttpClient();
        JSONObject jsonResult = null;
        HttpPost method = new HttpPost(url);
        try {
            if (null != jsonParam) {
                //解决中文乱码问题
                StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
                entity.setContentEncoding("UTF-8");
                entity.setContentType("application/json");
                method.setEntity(entity);
            }
            HttpResponse result = httpClient.execute(method);
            url = URLDecoder.decode(url, "UTF-8");
            //请求发送成功，并得到响应
            if (result.getStatusLine().getStatusCode() == 200) {
                String str = "";
                try {
                    //读取服务器返回过来的json字符串数据
                    str = EntityUtils.toString(result.getEntity());
                    if (noNeedResponse) {
                        return null;
                    }
                    //把json字符串转换成json对象
                    if(CommonUtils.isJson(str)){
                    	jsonResult = JSONObject.parseObject(str);
                    }
                } catch (Exception e) {
                    logger.error("post请求提交失败:" + url, e);
                }
            }
        } catch (IOException e) {
            logger.error("post请求提交失败:" + url, e);
        }
        return jsonResult;
    }
    
}
